package org.hilo.boot.core.db;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author zollty
 * @since 2018年6月8日
 */
public class DataSourceAopHelper {
    private static final Logger logger = LoggerFactory.getLogger(DataSourceAopHelper.class);
    /** Query method Name prefix */
    public final static String[] QUERY_PREFIX = { "select", "query", "find", "get", "exists" };

    /**
     * Read/Write Splitting
     * 
     * @param slaveDbKey Slave DB LookupKey
     */
    public static void switchDataSourceRWSplit(JoinPoint point, String slaveDbKey) {
        Boolean isQueryMethod = isQueryMethod(point.getSignature().getName());
        if (isQueryMethod) {
            DataSourceKeyHolder.setLookupKey(slaveDbKey == null ? "slave" : slaveDbKey);
            return;
        }
        // 默认主
        DataSourceKeyHolder.setLookupKey(null);
    }

    /**
     * Test the methodName is a query method or not.
     */
    public static Boolean isQueryMethod(String methodName) {
        for (String prefix : QUERY_PREFIX) {
            if (methodName.startsWith(prefix)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Get the Annotation {@link SelectDB} at the JoinPoint Method.
     */
    public static String getAnnotationValue(JoinPoint point) {
        // 获得当前访问的class
//        Class<?> clazz = point.getTarget().getClass();
        // 获得访问的方法名
//        String methodName = point.getSignature().getName();
        // 得到方法的参数的类型
//        Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getParameterTypes();
        try {
//            Method m = clazz.getMethod(methodName, parameterTypes);
            Method m = ((MethodSignature) point.getSignature()).getMethod();
            if (m != null && m.isAnnotationPresent(SelectDB.class)) {
                SelectDB val = m.getAnnotation(SelectDB.class);
                return val.value();
            }
        } catch (Exception e) {
            logger.warn("", e);
        }
        return null;
    }

}
